GtkTextView: Support font features
authorMatthias Clasen <mclasen@redhat.com>
Wed, 29 Jul 2015 22:28:56 +0000 (18:28 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 30 Jul 2015 01:42:58 +0000 (21:42 -0400)
Add a ::font-features attribute to GtkTextTag, and support
font features when inserting Pango markup into a text buffer.

gtk/gtktextattributes.c
gtk/gtktextattributes.h
gtk/gtktextbuffer.c
gtk/gtktextlayout.c
gtk/gtktexttag.c
gtk/gtktexttagprivate.h

index dc1360caf505316f5d48233edfd5087988abbe35..21a9d056093d80eea444baad709713fb4c6caaab 100644 (file)
@@ -143,6 +143,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   if (dest->appearance.rgba[1])
     gdk_rgba_free (dest->appearance.rgba[1]);
 
+  if (dest->font_features)
+    g_free (dest->font_features);
+
   /* Copy */
   orig_refcount = dest->refcount;
 
@@ -170,13 +173,16 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   if (src->appearance.rgba[1])
     dest->appearance.rgba[1] = gdk_rgba_copy (src->appearance.rgba[1]);
 
+  if (src->font_features)
+    dest->font_features = g_strdup (src->font_features);
+
   dest->refcount = orig_refcount;
 }
 
 /**
  * gtk_text_attributes_ref:
  * @values: a #GtkTextAttributes
- * 
+ *
  * Increments the reference count on @values.
  *
  * Returns: the #GtkTextAttributes that were passed in
@@ -228,6 +234,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
       if (values->appearance.rgba[1])
        gdk_rgba_free (values->appearance.rgba[1]);
 
+      if (values->font_features)
+        g_free (values->font_features);
+
       g_slice_free (GtkTextAttributes, values);
     }
 }
@@ -403,6 +412,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
       if (tag->priv->letter_spacing_set)
         dest->letter_spacing = vals->letter_spacing;
 
+      if (tag->priv->font_features_set)
+        dest->font_features = g_strdup (vals->font_features);
+
       ++n;
     }
 
@@ -430,6 +442,7 @@ _gtk_text_tag_affects_size (GtkTextTag *tag)
     priv->underline_set ||
     priv->wrap_mode_set ||
     priv->invisible_set ||
+    priv->font_features_set ||
     priv->letter_spacing_set;
 }
 
index 83a6312bd4158d414c8a52c342c489d306203e80..77c70f1a63c6ef9ab62d9b4686dcbe3ba6b7fae1 100644 (file)
@@ -207,8 +207,23 @@ struct _GtkTextAttributes
   /*< public >*/
   gint letter_spacing;
 
+#ifdef __GI_SCANNER__
+  /* The scanner should only see the transparent union, so that its
+   * content does not vary across architectures.
+   */
+  union {
+    gchar *font_features;
+    /*< private >*/
+    guint padding[2];
+  };
+#else
+  gchar *font_features;
+#if (defined(__SIZEOF_INT__) && defined(__SIZEOF_POINTER__)) && (__SIZEOF_INT__ == __SIZEOF_POINTER__)
+  /* unusable, just for ABI compat */
   /*< private >*/
-  guint padding[2];
+  guint padding[1];
+#endif
+#endif
 };
 
 GDK_AVAILABLE_IN_ALL
index 5bb9a210b85f9ccfed153445e0c01be7cc5e83ef..8e3e1de04e3151a1fe7b8ce7af1914383954ed1d 100644 (file)
@@ -4837,6 +4837,10 @@ get_tag_for_attributes (PangoAttrIterator *iter)
   if (attr)
     g_object_set (tag, "letter-spacing", ((PangoAttrInt*)attr)->value, NULL);
 
+  attr = pango_attr_iterator_get (iter, PANGO_ATTR_FONT_FEATURES);
+  if (attr)
+    g_object_set (tag, "font-features", ((PangoAttrString*)attr)->value, NULL);
+
   return tag;
 }
 
index 763ef3b7c8007ae318ec38dd4056894cc5bb6a9e..041f062f11cff5d3c0d3e8525d85ff1b377923f8 100644 (file)
@@ -1639,10 +1639,9 @@ add_text_attrs (GtkTextLayout      *layout,
   if (style->font_scale != 1.0)
     {
       attr = pango_attr_scale_new (style->font_scale);
-
       attr->start_index = start;
       attr->end_index = start + byte_count;
-      
+
       pango_attr_list_insert (attrs, attr);
     }
 
@@ -1661,6 +1660,15 @@ add_text_attrs (GtkTextLayout      *layout,
       attr->start_index = start;
       attr->end_index = start + byte_count;
 
+      pango_attr_list_insert (attrs, attr);
+    }
+
+  if (style->font_features)
+    {
+      attr = pango_attr_font_features_new (style->font_features);
+      attr->start_index = start;
+      attr->end_index = start + byte_count;
+
       pango_attr_list_insert (attrs, attr);
     }
 }
index 58ab9fa9714a87994d186d58f6452d5ec57547cb..9a11050ca6e087a06f06586a31abd2321587a867 100644 (file)
@@ -134,10 +134,11 @@ enum {
   PROP_PARAGRAPH_BACKGROUND_RGBA,
   PROP_FALLBACK,
   PROP_LETTER_SPACING,
+  PROP_FONT_FEATURES,
 
   /* Behavior args */
   PROP_ACCUMULATIVE_MARGIN,
-  
+
   /* Whether-a-style-arg-is-set args */
   PROP_BACKGROUND_SET,
   PROP_FOREGROUND_SET,
@@ -169,6 +170,7 @@ enum {
   PROP_PARAGRAPH_BACKGROUND_SET,
   PROP_FALLBACK_SET,
   PROP_LETTER_SPACING_SET,
+  PROP_FONT_FEATURES_SET,
 
   LAST_ARG
 };
@@ -676,6 +678,22 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
                                                      P_("Extra spacing between graphemes"),
                                                      0, G_MAXINT, 0,
                                                      GTK_PARAM_READWRITE));
+
+  /**
+   * GtkTextTag:font-features:
+   *
+   * OpenType font features, as a string.
+   *
+   * Since: 3.18
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_FONT_FEATURES,
+                                   g_param_spec_string ("font-features",
+                                                        P_("Font Features"),
+                                                        P_("OpenType Font Features to use"),
+                                                        NULL,
+                                                        GTK_PARAM_READWRITE));
+
   /**
    * GtkTextTag:accumulative-margin:
    *
@@ -833,6 +851,10 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
                 P_("Letter spacing set"),
                 P_("Whether this tag affects letter spacing"));
 
+  ADD_SET_PROP ("font-features-set", PROP_FONT_FEATURES_SET,
+                P_("Font features set"),
+                P_("Whether this tag affects font features"));
+
   /**
    * GtkTextTag::event:
    * @tag: the #GtkTextTag on which the signal is emitted
@@ -1643,6 +1665,12 @@ gtk_text_tag_set_property (GObject      *object,
       g_object_notify (object, "letter-spacing-set");
       break;
 
+    case PROP_FONT_FEATURES:
+      priv->font_features_set = TRUE;
+      priv->values->font_features = g_value_dup_string (value);
+      g_object_notify (object, "font-features-set");
+      break;
+
     case PROP_ACCUMULATIVE_MARGIN:
       priv->accumulative_margin = g_value_get_boolean (value);
       g_object_notify (object, "accumulative-margin");
@@ -1785,6 +1813,10 @@ gtk_text_tag_set_property (GObject      *object,
       priv->letter_spacing_set = g_value_get_boolean (value);
       break;
 
+    case PROP_FONT_FEATURES_SET:
+      priv->font_features_set = g_value_get_boolean (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2002,6 +2034,10 @@ gtk_text_tag_get_property (GObject      *object,
       g_value_set_int (value, priv->values->letter_spacing);
       break;
 
+    case PROP_FONT_FEATURES:
+      g_value_set_string (value, priv->values->font_features);
+      break;
+
     case PROP_ACCUMULATIVE_MARGIN:
       g_value_set_boolean (value, priv->accumulative_margin);
       break;
@@ -2118,6 +2154,10 @@ gtk_text_tag_get_property (GObject      *object,
       g_value_set_boolean (value, priv->letter_spacing_set);
       break;
 
+    case PROP_FONT_FEATURES_SET:
+      g_value_set_boolean (value, priv->font_features_set);
+      break;
+
     case PROP_BACKGROUND:
     case PROP_FOREGROUND:
     case PROP_PARAGRAPH_BACKGROUND:
index cd31b7cb2c057a806c4056a43cc3846d2f7c6a0c..26f30263d6a730eeeaf95a16835b6c0a00e5987e 100644 (file)
@@ -77,6 +77,7 @@ struct _GtkTextTagPrivate
   guint pg_bg_color_set : 1;
   guint fallback_set : 1;
   guint letter_spacing_set : 1;
+  guint font_features_set : 1;
 
   /* Whether these margins accumulate or override */
   guint accumulative_margin : 1;